const _ = require("lodash");
const fs = require("fs-extra");
const path = require("path");
const uuid = require("uuid/v1");
const moment = require("moment");
const router = require("koa-router")();
const jwt = require("jsonwebtoken");
const shelljs = require("shelljs");
const prettyBytes = require("pretty-file-bytes");
/**
 * api {get} /home/apps 应用列表
 *
 */
router.get("/apps", async (ctx, nex) => {
  const user = ctx.user;
  const baasIds = [];
  // 查询用户所有的应用id
  const apps = await BaaS.Models.user_baas
    .query(qb => {
      qb.where("user_id", "=", user.id);
    })
    .fetchAll({
      withRelated: ["charges", "baas"]
    });
  const appList = [];
  for (const key in apps) {
    if (apps[key].baas.id) {
      appList.push(apps[key]);
    }
  }
  for (const key in appList) {
    const baasToken = jwt.sign(appList[key].baas, ctx.config("jwt.secret"), {
      expiresIn: ctx.config("jwt.expiresIn")
    });
    appList[key].baas_token = baasToken;
    // 统计所有应用的所有统计数据
    const allLog = await BaaS.Models.statistics
      .query(qb => {
        qb.where(
          "created_at",
          ">",
          `${moment()
            .subtract(1, "months")
            .format("YYYY-MM-DD")}`
        );
        qb.where("baas_id", "=", appList[key].baas_id);
      })
      .fetchAll();
    const totalLog = {};
    let allRequest = 0;
    let allFlow = 0;
    let allStorage = 0;
    let allDebug = 0;
    // 统计流量和内存
    for (const log of allLog) {
      allRequest += log.request_num;
      allDebug += log.debug;
      allFlow += ctx.format(log.flow);
    }
    allStorage = _.last(allLog);
    allStorage = ctx.format(allStorage.storage);
    // 格式化流量和存储
    allFlow = prettyBytes(allFlow);
    allStorage = prettyBytes(allStorage);
    Object.assign(
      totalLog,
      { request: allRequest },
      { flow: allFlow },
      { storage: allStorage },
      { debug: allDebug }
    );
    appList[key].totalLog = totalLog;
  }
  const charges = await BaaS.Models.charges.query({}).fetchAll();
  // 查询用户是否领过新用户优惠券
  const createDate = moment(user.created_at).format("YYYY-MM-DD");
  const nowDate = moment().format("YYYY-MM-DD");
  let isGetCoupon = 1;
  const costLog = await BaaS.Models.cost_log
    .query({ where: { user_id: user.id } })
    .fetchAll();
  if (createDate == nowDate && user.money == 0 && costLog.length == 0) {
    isGetCoupon = 0;
  }
  ctx.success({ appList, charges, isGetCoupon });
});
/**
 * api {get} /home/apps 应用列表
 *
 */
router.get("/charges", async (ctx, nex) => {
  const charges = await BaaS.Models.charges.query({}).fetchAll();
  ctx.success(charges);
});
/**
 * api {post} /home/appAdd 新增应用
 *
 * apiParam {String} name 应用名称
 *
 */
router.post("/appAdd", async (ctx, nex) => {
  const user = ctx.user;
  const { name, engine = 1, feeId, chargesId } = ctx.post;
  const appList = await BaaS.Models.baas
    .query(qb => {
      qb.column("appid");
    })
    .fetchAll();
  // 获取不重复的appid
  const appid = ctx.randomCode(ctx.config("appidLength"));
  const appkey = uuid();
  // 获取不重复appid;
  const getNewAppid = await new Promise((resolve, reject) => {
    getName(appid, appList);
    function getName(appid, appList) {
      const repeat = ctx.repeatAppid(appid, appList);
      if (repeat) {
        const newAppid = ctx.randomCode(ctx.config("appidLength"));
        getName(newAppid, appList);
      } else {
        resolve(appid);
      }
    }
  });
  const key = `name:${name}:appid:${getNewAppid}:appkey:${appkey}`;
  const locked = await BaaS.redis.lock(key);
  if (locked) {
    // 添加到baas表
    const result = await BaaS.Models.baas
      .forge({
        name: name,
        appid: getNewAppid,
        appkey: appkey,
        database: "baas_" + appid
      })
      .save({
        withRedisKey: `baas:*:appid:${getNewAppid}:appkey:${appkey}:baas`
      });
    // 新增domain
    await BaaS.Models.domain
      .forge({ baas_id: result.id, name: `${result.appid}.dev.qingful.com` })
      .save();
    // 添加到user_baas表
    await BaaS.Models.user_baas
      .forge({
        user_id: user.id,
        baas_id: result.id,
        engine: engine,
        charges_id: chargesId
      })
      .save();
    // 新建该用户与对应文件夹
    try {
      // 创建域名配置文件
      await fs.outputFile(
        path.resolve(ctx.config("nginx"), `${appid}.conf`),
        `server {
    listen 80;
    server_name ${appid}.dev.qingful.com; #主机名称，绑定的域名
    root /www/baas-web/${appid};

    location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$ {
        expires 30d;
    }

    location ~ .*\.(js|css)$ {
        expires 10d;
    }

    location / {
        index index.html index.htm index_prod.html;
    }
}`
      );
      shelljs.exec("/usr/sbin/nginx -s reload");
      // 新建该应用的数据库
      const addDatabase = (await BaaS.bookshelf.knex.raw(
        "CREATE DATABASE `baas_" + appid + "`"
      ))[0];
      // 创建应用对应的文件夹
      fs.ensureDirSync(path.join(ctx.config("web"), appid));
      ctx.success("创建成功");
    } catch (err) {
      console.log(err);
      ctx.error("添加失败");
    }

    await BaaS.redis.unlock(key);
  } else {
    console.log(`${key} Waiting`);
  }
});
/**
 *
 * api {post} /home/getCoupon 领取优惠券
 *
 */
router.post("/appDelete", async (ctx, nex) => {
  const { baasId, name } = ctx.post;
  const userBaas = await BaaS.Models.user_baas
    .query({ where: { baas_id: baasId } })
    .fetch({
      withRelated: [
        "baas",
        {
          baas: qb => {
            qb.where("name", "=", name);
          }
        }
      ]
    });
  if (userBaas.baas.id) {
    await BaaS.Models.baas.forge({ id: baasId }).destroy();
    ctx.success("删除成功");
  } else {
    ctx.error("不存在该应用");
  }
});
/**
 * api {get} /home/notice 获取提醒
 *
 * apiParam {String} app_name 应用名称
 *
 */
router.get("/notice", async (ctx, nex) => {
  const user = ctx.user;
  const notices = await BaaS.Models.user_notice
    .query(qb => {
      qb.where("user_id", "=", user.id);
    })
    .fetchAll({ withRelated: ["notice"] });
  ctx.success(notices);
});
/**
 *
 * api {get} /home/notice/:id 提醒修改成已读
 *
 */
router.get("/notice/:id", async (ctx, nex) => {
  const ids = ctx.params.id;
  const user = ctx.user;
  const idArr = ids.split(",");
  const noticeArr = [];
  for (const id of idArr) {
    noticeArr.push({ id: id, status: 1 });
  }
  // 批量更新消息状态
  await BaaS.bookshelf.Collection.extend({
    model: BaaS.Models.user_notice
  })
    .forge(noticeArr)
    .invokeThen("save");

  ctx.success("修改成功");
});
/**
 *
 * api {get} /home/notice/:id 提醒批量删除
 *
 */
router.get("/notice/delete/:id", async (ctx, nex) => {
  const ids = ctx.params.id;
  const idArr = ids.split(",");
  const deleteArr = [];
  for (const id of idArr) {
    deleteArr.push({ id: id });
  }
  // 批量删除消息状态
  const delRes = await BaaS.bookshelf.Collection.extend({
    model: BaaS.Models.user_notice
  })
    .forge(deleteArr)
    .invokeThen("destroy");
  ctx.success("删除成功");
});
/**
 *
 * api {post} /home/getCoupon 领取优惠券
 *
 */
router.post("/getCoupon", async (ctx, nex) => {
  const user = ctx.user;
  const createDate = moment(user.created_at).format("YYYY-MM-DD");
  const nowDate = moment().format("YYYY-MM-DD");
  if (createDate == nowDate && user.money == 0) {
    await BaaS.Models.user.forge({ id: user.id, money: 60 }).save();
    ctx.success("兑换成功");
  } else {
    ctx.error("已领取");
  }
});

module.exports = router;
